package com.jwiki.app.rpcui.menu.setup;

import java.io.File;
import java.util.Iterator;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import com.jwiki.app.rpcui.attribute.ApiJarAttribute;
import com.jwiki.app.rpcui.config.Configurations;
import com.jwiki.app.rpcui.util.SwtUtils;

public class AddJarFileDialog extends Dialog {

    protected Object result;
    protected Shell shellAddJarFile;
    private Text txtJarFile;
    private Text txtArtifactId;
    private Text txtVersion;
    private Text txtGroupId;

    private ApiJarFileDialog apiJarFileDialog;
    private Table tblJarFiles;
    private Button btnRemove;

    /**
     * Create the dialog.
     * @param parent
     * @param style
     */
    public AddJarFileDialog(ApiJarFileDialog refDialog, Shell parent, int style) {
        super(parent, style | SwtUtils.DIALOG_RESIZE);
        apiJarFileDialog = refDialog;
    }

    /**
     * Open the dialog.
     * @return the result
     */
    public Object open() {
        createContents();
        SwtUtils.centerDialog(shellAddJarFile, getParent());
        shellAddJarFile.open();
        shellAddJarFile.layout();
        Display display = getParent().getDisplay();
        while (!shellAddJarFile.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        return result;
    }

    /**
     * Create contents of the dialog.
     */
    private void createContents() {
        shellAddJarFile = new Shell(getParent(), getStyle());
        shellAddJarFile.setImages(Configurations.DEFAULT_ICON_IMAGES);
        shellAddJarFile.setSize(451, 433);
        shellAddJarFile.setText("Add Jar File");
        GridLayout gl_shellAddJarFile = new GridLayout(1, false);
        gl_shellAddJarFile.marginWidth = 0;
        gl_shellAddJarFile.marginHeight = 0;
        shellAddJarFile.setLayout(gl_shellAddJarFile);

        Composite composite = new Composite(shellAddJarFile, SWT.NONE);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        composite.setLayout(new GridLayout(3, false));

        Label lblJarFile = new Label(composite, SWT.NONE);
        lblJarFile.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblJarFile.setText("Api Jar File :");

        txtJarFile = new Text(composite, SWT.BORDER);
        txtJarFile.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Button btnScan = new Button(composite, SWT.NONE);
        btnScan.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                String jarFilePath = openJarFileDialog();
                if (StringUtils.isNotEmpty(jarFilePath)) {
                    txtJarFile.setText(jarFilePath);
                }
            }
        });
        GridData gd_btnScan = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        gd_btnScan.widthHint = 24;
        btnScan.setLayoutData(gd_btnScan);
        btnScan.setText("...");

        Label lblGroupId = new Label(composite, SWT.NONE);
        lblGroupId.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblGroupId.setText("Group Id :");

        txtGroupId = new Text(composite, SWT.BORDER);
        txtGroupId.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

        Label lblArtifactId = new Label(composite, SWT.NONE);
        lblArtifactId.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblArtifactId.setText("Artifact Id :");

        txtArtifactId = new Text(composite, SWT.BORDER);
        txtArtifactId.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

        Label lblVersion = new Label(composite, SWT.NONE);
        lblVersion.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblVersion.setText("Version :");

        txtVersion = new Text(composite, SWT.BORDER);
        txtVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        new Label(composite, SWT.NONE);
        new Label(composite, SWT.NONE);
        new Label(composite, SWT.NONE);

        Label lblDependencyJarFile = new Label(composite, SWT.NONE);
        GridData gd_lblDependencyJarFile = new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1);
        gd_lblDependencyJarFile.widthHint = 123;
        lblDependencyJarFile.setLayoutData(gd_lblDependencyJarFile);
        lblDependencyJarFile.setText("Dependency Jar Files");

        Composite compDependencyJarFile = new Composite(composite, SWT.NONE);
        GridLayout gl_compDependencyJarFile = new GridLayout(2, false);
        gl_compDependencyJarFile.marginWidth = 0;
        gl_compDependencyJarFile.marginHeight = 0;
        compDependencyJarFile.setLayout(gl_compDependencyJarFile);
        compDependencyJarFile.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));

        tblJarFiles = new Table(compDependencyJarFile, SWT.BORDER | SWT.FULL_SELECTION);
        tblJarFiles.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (tblJarFiles.getSelectionCount() > 0) {
                    btnRemove.setEnabled(true);
                }
            }
        });
        GridData gd_tblJarFiles = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
        gd_tblJarFiles.heightHint = 126;
        tblJarFiles.setLayoutData(gd_tblJarFiles);
        tblJarFiles.setHeaderVisible(true);
        tblJarFiles.setLinesVisible(true);

        TableColumn tblclmnFileName = new TableColumn(tblJarFiles, SWT.NONE);
        tblclmnFileName.setWidth(98);
        tblclmnFileName.setText("File Name");

        TableColumn tblclmnFilePath = new TableColumn(tblJarFiles, SWT.NONE);
        tblclmnFilePath.setWidth(219);
        tblclmnFilePath.setText("File Path");

        Composite compJarFileAction = new Composite(compDependencyJarFile, SWT.NONE);
        GridData gd_compJarFileAction = new GridData(SWT.RIGHT, SWT.TOP, false, true, 1, 1);
        gd_compJarFileAction.heightHint = 61;
        gd_compJarFileAction.widthHint = 80;
        compJarFileAction.setLayoutData(gd_compJarFileAction);

        Button btnAdd = new Button(compJarFileAction, SWT.NONE);
        btnAdd.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                String jarFilePath = openJarFileDialog();
                if (StringUtils.isNotEmpty(jarFilePath)) {
                    TableItem tableItem = new TableItem(tblJarFiles, SWT.NONE);
                    tableItem.setText(0, FilenameUtils.getName(jarFilePath));
                    tableItem.setText(1, jarFilePath);
                }
            }
        });
        btnAdd.setBounds(0, 0, 80, 27);
        btnAdd.setText("Add...");

        btnRemove = new Button(compJarFileAction, SWT.NONE);
        btnRemove.setEnabled(false);
        btnRemove.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                for (int index : tblJarFiles.getSelectionIndices()) {
                    tblJarFiles.remove(index);
                }
            }
        });
        btnRemove.setBounds(0, 33, 80, 27);
        btnRemove.setText("Remove");

        Composite compJarAction = new Composite(shellAddJarFile, SWT.NONE);
        compJarAction.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        compJarAction.setLayout(new GridLayout(1, false));

        Label label = new Label(compJarAction, SWT.SEPARATOR | SWT.HORIZONTAL);
        label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

        Composite composite_2 = new Composite(compJarAction, SWT.NONE);
        composite_2.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));

        Button btnClose = new Button(composite_2, SWT.NONE);
        btnClose.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                shellAddJarFile.close();
                shellAddJarFile.dispose();
            }
        });
        btnClose.setBounds(86, 0, 80, 27);
        btnClose.setText("Close");

        Button btnOk = new Button(composite_2, SWT.NONE);
        btnOk.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                try {
                    Iterator<File> iterator = FileUtils.iterateFiles(new File(Configurations.DIR_API),
                            new String[] { "jar" }, false);
                    File artifactFile = null;
                    while (iterator.hasNext()) {
                        File tempFile = iterator.next();
                        if (tempFile.getName().contains(txtArtifactId.getText())) {
                            artifactFile = tempFile;
                            break;
                        }
                    }

                    boolean doContinue = true;
                    if (artifactFile != null) {
                        boolean callable = MessageDialog.openConfirm(shellAddJarFile, "Confirm Override",
                                "File \"" + artifactFile.getName() + "\" has same artifact Id. " +
                                "Are you sure you want to override this file?");
                        if (callable) {
                            FileUtils.forceDelete(artifactFile);
                        } else {
                            doContinue = false;
                        }
                    }

                    if (doContinue) {
                        // create attribute of jar
                        ApiJarAttribute attribute = new ApiJarAttribute();
                        attribute.setDirectory(txtJarFile.getText());
                        attribute.setName(FilenameUtils.getName(txtJarFile.getText()));
                        attribute.setGroupId(txtGroupId.getText());
                        attribute.setArtifactId(txtArtifactId.getText());
                        attribute.setVersion(txtVersion.getText());
                        // add dependency files
                        if (tblJarFiles.getItemCount() > 0) {
                            String[] dependencies = new String[tblJarFiles.getItemCount()];
                            for (int i = 0; i < tblJarFiles.getItemCount(); i++) {
                                dependencies[i] = tblJarFiles.getItem(i).getText(1);
                            }
                            attribute.setDependencies(dependencies);
                        }
                        apiJarFileDialog.importAndParseJarFile(attribute);
                        shellAddJarFile.close();
                        shellAddJarFile.dispose();
                    }
                } catch (Throwable ex) {
                    ex.printStackTrace();
                    Status status = new Status(IStatus.ERROR, "add_jar_file", ex.getMessage(), ex);
                    ErrorDialog errorDialog = new ErrorDialog(shellAddJarFile, "Error Information", ex.getMessage(),
                            status, IStatus.ERROR);
                    errorDialog.open();
                }
            }
        });
        btnOk.setEnabled(false);
        btnOk.setBounds(0, 0, 80, 27);
        btnOk.setText("OK");

        // check enabled status of OK button
        SwtUtils.addRequiredInputListener(composite.getChildren(), new Control[] { btnOk });
    }

    protected String openJarFileDialog() {
        FileDialog dialog = new FileDialog(shellAddJarFile, SWT.OPEN);
        dialog.setFilterPath(System.getProperty("java.home"));
        dialog.setFilterExtensions(new String[] { "*.jar", "*.*" });
        dialog.setFilterNames(new String[] { "Jar Files (*.jar)", "All Files (*.*)" });
        return dialog.open();
    }

}
